﻿using Padsurface.CoreAudio.Components.MMDevice;
using Padsurface.CoreAudio.Components.MMDevice.Interfaces;
using Padsurface.CoreAudio.Components.WASAPI.Interfaces;
using Padsurface.CoreAudio.Wrappers.Services.Interfaces;
using System;
using System.Composition;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Windows.Media.Devices;

namespace Padsurface.CoreAudio.Wrappers.Services
{
    [Export(typeof(IAudioClientActivator))]
    internal class AudioClientActivator : IAudioClientActivator
    {
        private IActivateAudioInterfaceCompletionHandler _completionHandler;
        private TaskCompletionSource<IAudioClient> _taskCompletionSource;

        public AudioClientActivator()
        {
            _completionHandler = new ActivateAudioInterfaceCompletionHandler();
            _completionHandler.InterfaceActivated += (s, e) => OnInterfaceActivated(_taskCompletionSource, e);
        }

        public Task<IAudioClient> Activate()
        {
            var defaultAudioCaptureId = MediaDevice.GetDefaultAudioCaptureId(AudioDeviceRole.Default);
            IActivateAudioInterfaceAsyncOperation createAsync;

            Marshal.ThrowExceptionForHR(
                WindowsMultimediaDevice.ActivateAudioInterfaceAsync(
                    defaultAudioCaptureId, new Guid(Padsurface.CoreAudio.Components.WASAPI.ComIIDs.IAudioClientIID), IntPtr.Zero, _completionHandler, 
                    out createAsync));

            _taskCompletionSource = new TaskCompletionSource<IAudioClient>();
            return _taskCompletionSource.Task;
        }

        private static void OnInterfaceActivated(TaskCompletionSource<IAudioClient> taskCompletionSource, InterfaceActivatedEventArgs e)
        {
            if (e.Exception != null)
                taskCompletionSource.SetException(e.Exception);
            else
                taskCompletionSource.SetResult(e.ActivatedInterface as IAudioClient);
        }
    }
}
